package com.blog.cloud.auth.controller;

import com.blog.cloud.api.dto.MobileLoginDto;
import com.blog.cloud.api.dto.NameLoginDto;
import com.blog.cloud.api.dto.UserRegisterDto;
import com.blog.cloud.api.vo.auth.UserVO;
import com.blog.cloud.auth.service.AuthService;
import com.blog.cloud.core.utils.R;
import com.xkcoding.justauth.AuthRequestFactory;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;

@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
public class AuthController {
    private final AuthRequestFactory factory;
    private final AuthService authService;

    /**
     * 通过手机号和验证码登录
     * @param loginDto 登录参数
     * @return 用户信息
     */
    @PostMapping("/loginByUsername")
    public R<UserVO> loginByUsername(@RequestBody @Valid NameLoginDto loginDto) {
        UserVO userVO = authService.loginByUsername(loginDto);
        return R.ok(userVO);
    }

    /**
     * 通过手机号和验证码登录
     * @param loginDto 登录参数
     * @return 用户信息
     */
    @PostMapping("/loginByMobile")
    public R<UserVO> loginByMobile(@RequestBody @Valid MobileLoginDto loginDto) {
        UserVO userVO = authService.loginByMobile(loginDto);
        return R.ok(userVO);
    }

    /**
     * 用户注册
     * @param registerDto 注册信息
     * @return 注册结果
     */
    @PostMapping("/register")
    public R<Boolean> register(@RequestBody @Valid UserRegisterDto registerDto) {
        Boolean result = authService.register(registerDto);
        return R.ok();
    }

    /**
     * 三方授权登录
     * @param type 第三方标识
     * @param response 响应信息
     * @throws IOException 异常
     */
    @GetMapping("/login/{type}")
    public void loginBySource(@PathVariable String type, HttpServletResponse response) throws IOException {
        AuthRequest authRequest = factory.get(type);
        String redirectUrl = authRequest.authorize(AuthStateUtils.createState());
        response.sendRedirect(redirectUrl);
    }

    /**
     * 授权回调
     * @param type 第三方标识
     * @param callback 回调关键信息
     * @return 用户信息
     */
    @GetMapping("/{type}/callback")
    public R<Object> callBack(@PathVariable String type, AuthCallback callback) {
        AuthRequest authRequest = factory.get(type);
        AuthResponse response = authRequest.login(callback);
        // TODO 从response中封装UserInfoVO用户信息，然后返回给前端
        if (response.getCode() != 2000) {
            return R.failed("授权获取用户信息失败");
        }
        AuthUser authUser = (AuthUser) response.getData();
        UserVO userVO = authService.callBack(authUser);

        Object data = (AuthUser)response.getData();
        return R.ok(data);
    }
}
